﻿using System;
using System.Collections.Generic;
using UnityEngine;
using System.Collections;

/// <summary>
/// 计时器(防后台)
/// </summary>
public class TimeManage : MonoBehaviour
{
    private static TimeManage self;

    private Dictionary<int, ArrayList> typeFuncArr = new Dictionary<int, ArrayList>();

    private Stack<int> indexStack = new Stack<int>();

    private Dictionary<int, DispatchEventHandler> EventTable;

    private List<int> needRemoveIndex = new List<int>();

    public delegate void DispatchEventHandler(System.Object sender, DispatchEventArgs e);
    public event DispatchEventHandler Dispatch;

    public static TimeManage getInstance()
    {
        if (self == null)
        {
            self = Camera.mainCamera.GetComponent<TimeManage>();
        }
        return self;
    }

    void Awake()
    {
        EventTable = new Dictionary<int, DispatchEventHandler>();
        InvokeRepeating("onUpdate", 1, 1);
    }
    void onUpdate()
    {
        DateTime nowTime = DateTime.Now;

        Dictionary<int, ArrayList> tempDic = new Dictionary<int, ArrayList>(typeFuncArr);
        //foreach (KeyValuePair<int, ArrayList> enter in typeFuncArr)
        //{
        //    tempDic.Add(enter.Key, enter.Value);
        //}
        foreach (KeyValuePair<int, ArrayList> enter in tempDic)
        {
            ArrayList arr = enter.Value;
            DateTime startTime = (DateTime)arr[1];
            int countTime = (int)arr[2];
            TimeSpan compareTime = nowTime.Subtract(startTime);
            int lastSeconds = (int)Math.Round(compareTime.TotalSeconds);

            if (lastSeconds >= countTime)
            {
                dispacthEvent(enter.Key, new object[] { 0, arr });
                removeTimeEvent(enter.Key);
            }
            else
            {
                dispacthEvent(enter.Key, new object[] { countTime - lastSeconds, arr });
            }
        }
    }


    public int Count
    {
        get { return EventTable.Count; }
    }


    private void dispacthEvent(int type, params object[] data)
    {
        if (EventTable.ContainsKey(type))
        {
            DispatchEventArgs e = new DispatchEventArgs(type, data);
            DispatchEventHandler funcArr = (DispatchEventHandler)EventTable[type];
            this.Dispatch = funcArr;
            OnDispatch(e);
        }
    }

    private void OnDispatch(DispatchEventArgs e)
    {
        if (Dispatch != null)
        {
            Dispatch(this, e);
        }
    }

    /// <summary>
    /// 增加计时器(func回调方法格式:(Object obj, DispatchEventArgs e)){ e.data[0] 为剩余秒数 }
    /// </summary>
    /// <param name="countTime">计时时间(s)</param>
    /// <return>计时器索引</return>
    public int addTimeEvent(int countTime, DispatchEventHandler func)
    {
        return addTimeEvent(countTime, null, func);
    }
    public int addTimeEvent(int countTime, object obj, DispatchEventHandler func)
    {
        DateTime nowTime = DateTime.Now;
        int index = 0;
        if (indexStack.Count < 1)
        {
            index = Count;
        }
        else
        {
            index = (int)indexStack.Pop();
        }

        if (!EventTable.ContainsKey(index))
        {
            EventTable.Add(index, func);
            ArrayList arr = new ArrayList();
            arr.Add(index);
            arr.Add(nowTime);
            arr.Add(countTime);
            if (obj != null) arr.Add(obj);
            if (!typeFuncArr.ContainsKey(index)) typeFuncArr.Add(index, arr);
        }

        return index;
    }

    /// <summary>
    /// 移除计时器
    /// </summary>
    /// <param name="index">计时器索引(addTimeEvent返回的索引值)</param>
    public void removeTimeEvent(int index)
    {
        if (indexStack.Contains(index) == false)
        {
            indexStack.Push(index);
        }

        if (typeFuncArr.ContainsKey(index))
        {
            typeFuncArr.Remove(index);
        }

        if (EventTable.ContainsKey(index))
        {
            EventTable.Remove(index);
        }
    }

    /// <summary>
    /// 转换秒为具体的时间(1:1:12:21 天:时:分:秒)
    /// </summary>
    /// <param name="t">秒</param>
    /// <returns>天:时:分:秒</returns>
    public string changeSecsToTime(int t)
    {
        string r = "";
        int day, hour, minute, second;

        day = Convert.ToInt16(t / 86400);
        hour = Convert.ToInt16((t % 86400) / 3600);
        minute = Convert.ToInt16((t % 86400 % 3600) / 60);
        second = Convert.ToInt16(t % 86400 % 3600 % 60);
        r = day + ":" + hour + ":" + minute + ":" + second;
        
        return r;
    }


}